package top.lingkang.screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.ai.msg.MessageManager;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import top.lingkang.MyGdxGame;
import top.lingkang.constants.AttackType;
import top.lingkang.constants.FlightType;
import top.lingkang.constants.MoveType;
import top.lingkang.constants.PlaneType;
import top.lingkang.screen.common.PlayStage;
import top.lingkang.sprite.BulletSprite;
import top.lingkang.sprite.EnemyPlaneSprite;
import top.lingkang.sprite.PlayerSprite;
import top.lingkang.sprite.PropSprite;

import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;

public class PlayScreen extends GameScreen {
    public MyGdxGame game;
    private SpriteBatch batch;
    public PlayStage stage;
    private TiledMap map;// 地图
    private OrthographicCamera camera;// 相机
    private OrthogonalTiledMapRenderer renderer;// 正交相机渲染
    public boolean cameraIsMove = true;
    public float cameraMoveSpeed = 0.5f;
    // 玩家
    public PlayerSprite playerPlane;
    // 敌人
    public Array<EnemyPlaneSprite> enemyPlane = new Array<>();
    // 子弹
    public final Array<BulletSprite> bulletSprites = new Array<>();
    // 子弹对象池
    public final Pool<BulletSprite> bulletPool = new Pool<BulletSprite>() {
        @Override
        protected BulletSprite newObject() {
            return new BulletSprite();
        }
    };
    // 敌人出现地点
    private HashMap<Float, EnemyPlaneSprite> enemyMap = new HashMap<>();
    // 道具
    public Array<PropSprite> propSprites = new Array<>();

    public MessageManager messageDispatcher;
    private PlayScreen playScreen = this;

    public PlayScreen(MyGdxGame game) {
        this.game = game;
        this.batch = game.batch;
        camera = game.camera;
        // 初始化舞台
        stage = new PlayStage(game.viewport);
        // 初始化资源
        loadAssets();

        // 加载地图 480*6000
        map = new TmxMapLoader().load("map1/map1.tmx");
        // 不切割单元
        renderer = new OrthogonalTiledMapRenderer(map, 2f);
        camera.setToOrtho(false, game.VIEW_WIDTH, game.VIEW_HEIGHT);
        camera.position.x = game.VIEW_WIDTH / 2;
        camera.position.y = game.VIEW_HEIGHT / 2;
        camera.update();

        playerPlane = new PlayerSprite(200, 100, 3, this);
        // 任务调度
        messageDispatcher = MessageManager.getInstance();

        // 添加敌人出现时钟
        addEnemy();
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // 清除屏幕
        // 用户输入
        userInput(delta);

        // 摄影机查看并渲染内容
        camera.update();
        renderer.setView(camera);
        renderer.render();

        if (cameraIsMove) {
            camera.position.y += cameraMoveSpeed;
            stage.distance.setText(String.valueOf(camera.position.y));
            if (camera.position.y > 6000f) {
                cameraIsMove = false;
                cameraMoveSpeed = 0f;
            }
        }

        batch.begin(); // 将绘制任务放下面 start
        // 绘制敌人
        updateEnemy(delta);

        // 绘制玩家
        playerPlane.update(batch, delta);

        // 子弹绘制和击中检测
        bulletCheck();

        // 绘制道具
        updatePropSprites();

        batch.end();// 绘制任务 end

        // 绘制舞台
        stage.draw();
    }

    private void updatePropSprites() {
        int size = propSprites.size;
        if (size == 0) {
            return;
        }
        PropSprite propSprite;
        for (int i = size; --i >= 0; ) {
            propSprite = propSprites.get(i);
            if (propSprite.alive) {
                propSprite.update(batch, 0);
            } else {
                // 移除
                propSprites.removeIndex(i);
            }
        }
    }

    private void bulletCheck() {
        // 绘制子弹
        int size = bulletSprites.size;
        if (size == 0) {
            return;
        }
        BulletSprite bulletSprite;
        for (int i = size; --i >= 0; ) {
            bulletSprite = bulletSprites.get(i);
            if (bulletSprite.alive) {// 子弹存活
                bulletSprite.update(batch);
            } else {
                // 移除子弹
                bulletSprites.removeIndex(i);
                // 释放子弹
                bulletPool.free(bulletSprite);
            }
        }
    }

    private void updateEnemy(float delta) {
        int size = enemyPlane.size;
        if (size == 0)
            return;
        for (int i = size; --i >= 0; ) {
            EnemyPlaneSprite enemyPlaneSprite = enemyPlane.get(i);
            if (enemyPlaneSprite.alive) {
                // 绘制敌人
                enemyPlaneSprite.update(batch, delta);
            } else {
                // 敌人死亡
                enemyPlane.removeIndex(i);
            }
        }
    }

    private void userInput(float delta) {
        // messageDispatcher.dispatchMessage(1);
        if (Gdx.input.isKeyPressed(Input.Keys.W)) {
            playerPlane.move(MoveType.UP);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.S)) {
            playerPlane.move(MoveType.DOWN);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.A)) {
            playerPlane.move(MoveType.LEFT);
        }
        if (Gdx.input.isKeyPressed(Input.Keys.D)) {
            playerPlane.move(MoveType.RIGHT);
        }
        // 子弹攻击
        if (Gdx.input.isKeyPressed(Input.Keys.SPACE)) {
            playerPlane.attack(this, delta);
        }
    }


    Timer timer1, timer2, timer3;

    private void addEnemy() {
        timer1 = new Timer();
        timer2 = new Timer();
        timer3 = new Timer();
        timer1.schedule(new TimerTask() {
            @Override
            public void run() {
                int x = (int) (Math.random() * 460);
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.NONE, AttackType.COMMON_1,
                        1, x, 648, playScreen));
            }
        }, 0, 4000);
        timer2.schedule(new TimerTask() {
            @Override
            public void run() {
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.LEFT_TO_RIGHT, AttackType.NONE,
                        1, -32, 648, playScreen));
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.LEFT_TO_RIGHT, AttackType.NONE,
                        MathUtils.random(1, 3), -64, 600, playScreen));
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.LEFT_TO_RIGHT, AttackType.NONE,
                        MathUtils.random(1, 3), -96, 500, playScreen));
            }
        }, 0, 10000);
        timer1.schedule(new TimerTask() {
            @Override
            public void run() {
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.UP_TO_DOWN, AttackType.COMMON_1,
                        MathUtils.random(1, 3), 100, 648, playScreen));
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.UP_TO_DOWN, AttackType.COMMON_1,
                        1, 200, 700, playScreen));
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.UP_TO_DOWN, AttackType.COMMON_1,
                        MathUtils.random(1, 3), 300, 730, playScreen));
                enemyPlane.add(new EnemyPlaneSprite(PlaneType.ENEMY_5, FlightType.UP_TO_DOWN, AttackType.COMMON_1,
                        MathUtils.random(1, 3), 400, 760, playScreen));
            }
        }, 0, 9000);
    }

    @Override
    public void dispose() {
        super.dispose();
        batch.dispose();
        stage.dispose();
        map.dispose();
        renderer.dispose();
        bulletPool.clear();
        playerPlane.dispose();
        timer1.cancel();
        timer2.cancel();
        timer3.cancel();


        // 清理资源
        game.assetManager.unload("tiles/t-0.png");
        game.assetManager.unload("tiles/t-9.png");
        game.assetManager.unload("plane/ship_0005.png");
        game.assetManager.unload("music/send.mp3");
        game.assetManager.unload("music/didi.mp3");
        game.assetManager.unload("music/jiangli.mp3");
        game.assetManager.unload("music/dingdong.mp3");
        game.assetManager.unload("music/wanmei.mp3");
        game.assetManager.unload("music/pengzhuang.mp3");
    }

    private void loadAssets() {
        game.assetManager.load("tiles/t-0.png", Texture.class);
        game.assetManager.load("tiles/t-9.png", Texture.class);
        game.assetManager.load("tiles/t-24.png", Texture.class);
        game.assetManager.load("tiles/t-25.png", Texture.class);
        game.assetManager.load("tiles/t-26.png", Texture.class);
        game.assetManager.load("plane/ship_0005.png", Texture.class);
        game.assetManager.load("music/send.mp3", Sound.class);
        game.assetManager.load("music/didi.mp3", Sound.class);
        game.assetManager.load("music/jiangli.mp3", Sound.class);
        game.assetManager.load("music/dingdong.mp3", Sound.class);
        game.assetManager.load("music/wanmei.mp3", Sound.class);
        game.assetManager.load("music/pengzhuang.mp3", Sound.class);
        // 同步加载资源
        game.assetManager.finishLoading();
    }
}
